from flask import render_template, redirect, url_for, flash, request, current_app
from . import bp
from app.models import db, Student, Course, Grade
from app.forms import StudentForm, CourseForm, GradeForm
from sqlalchemy.exc import IntegrityError

@bp.route('/')
@bp.route('/students')
def student_list():
    form = StudentForm()
    page = request.args.get('page', 1, type=int)
    pagination = Student.query.order_by(Student.student_id).paginate(
        page=page, per_page=current_app.config.get('ITEMS_PER_PAGE', 10), error_out=False)
    students = pagination.items
    return render_template('student_list.html', students=students, pagination=pagination, form=form)

@bp.route('/students/add', methods=['GET', 'POST'])  # Ensure both GET and POST methods are allowed
def student_add():
    form = StudentForm()  # Initialize the form
    if form.validate_on_submit():  # When the form is submitted and passes validation
        student = Student(student_id=form.student_id.data.strip(),
                          name=form.name.data.strip(),
                          class_name=form.class_name.data.strip())
        db.session.add(student)  # Add the student to the database
        try:
            db.session.commit()  # Commit the changes
            flash('学生已添加', 'success')  # Success message
            return redirect(url_for('main.student_list'))  # Redirect to the student list page
        except IntegrityError:  # If there's an IntegrityError (like duplicate student ID)
            db.session.rollback()  # Rollback the session
            flash('学号已存在，请使用不同学号', 'danger')  # Error message for duplicate student ID
    return render_template('student_form.html', form=form, title='添加学生')  # Render the form again if it's a GET request or validation failed


@bp.route('/students/edit/<int:id>', methods=['GET', 'POST'])
def student_edit(id):
    student = Student.query.get_or_404(id)
    form = StudentForm(obj=student)
    if form.validate_on_submit():
        student.student_id = form.student_id.data.strip()
        student.name = form.name.data.strip()
        student.class_name = form.class_name.data.strip()
        try:
            db.session.commit()
            flash('学生信息已更新', 'success')
            return redirect(url_for('main.student_list'))
        except IntegrityError:
            db.session.rollback()
            flash('学号冲突，请检查', 'danger')
    return render_template('student_form.html', form=form, title='编辑学生')

@bp.route('/students/delete/<int:id>', methods=['POST'])
def student_delete(id):
    student = Student.query.get_or_404(id)
    db.session.delete(student)
    db.session.commit()
    flash('学生已删除', 'info')
    return redirect(url_for('main.student_list'))

@bp.route('/students/<int:id>')
def student_detail(id):
    student = Student.query.get_or_404(id)
    return render_template('student_detail.html', student=student)

@bp.route('/courses')
def course_list():
    page = request.args.get('page', 1, type=int)
    pagination = Course.query.order_by(Course.course_code).paginate(
        page=page, per_page=current_app.config.get('ITEMS_PER_PAGE', 10), error_out=False)
    courses = pagination.items
    return render_template('course_list.html', courses=courses, pagination=pagination)

@bp.route('/courses/add', methods=['GET', 'POST'])
def course_add():
    form = CourseForm()
    if form.validate_on_submit():
        course = Course(course_code=form.course_code.data.strip(),
                        name=form.name.data.strip(),
                        credit=form.credit.data)
        db.session.add(course)
        try:
            db.session.commit()
            flash('课程已添加', 'success')
            return redirect(url_for('main.course_list'))
        except IntegrityError:
            db.session.rollback()
            flash('课程编号已存在', 'danger')
    return render_template('course_form.html', form=form, title='添加课程')

@bp.route('/courses/edit/<int:id>', methods=['GET', 'POST'])
def course_edit(id):
    course = Course.query.get_or_404(id)
    form = CourseForm(obj=course)
    if form.validate_on_submit():
        course.course_code = form.course_code.data.strip()
        course.name = form.name.data.strip()
        course.credit = form.credit.data
        try:
            db.session.commit()
            flash('课程信息已更新', 'success')
            return redirect(url_for('main.course_list'))
        except IntegrityError:
            db.session.rollback()
            flash('课程编号冲突', 'danger')
    return render_template('course_form.html', form=form, title='编辑课程')

@bp.route('/courses/delete/<int:id>', methods=['POST'])
def course_delete(id):
    course = Course.query.get_or_404(id)
    db.session.delete(course)
    db.session.commit()
    flash('课程已删除', 'info')
    return redirect(url_for('main.course_list'))

@bp.route('/grades')
@bp.route('/grades')
def grade_list():
    page = request.args.get('page', 1, type=int)
    query = Grade.query.join(Student).join(Course).order_by(Student.student_id, Course.course_code)
    
    # 使用关键字参数传递参数
    pagination = query.paginate(page=page, per_page=current_app.config.get('ITEMS_PER_PAGE', 10), error_out=False)
    
    grades = pagination.items
    return render_template('grade_list.html', grades=grades, pagination=pagination)


@bp.route('/grades/add', methods=['GET', 'POST'])
def grade_add():
    form = GradeForm()
    form.student.choices = [(s.id, f'{s.student_id} - {s.name}') for s in Student.query.order_by(Student.student_id).all()]
    form.course.choices = [(c.id, f'{c.course_code} - {c.name}') for c in Course.query.order_by(Course.course_code).all()]
    if form.validate_on_submit():
        existing = Grade.query.filter_by(student_id=form.student.data, course_id=form.course.data).first()
        if existing:
            flash('该学生该课程已有成绩记录，请编辑已有记录', 'warning')
            return redirect(url_for('main.grade_edit', id=existing.id))
        grade = Grade(student_id=form.student.data,
                      course_id=form.course.data,
                      score=form.score.data,
                      grade_status=form.grade_status.data.strip() or None)
        db.session.add(grade)
        try:
            db.session.commit()
            flash('成绩已添加', 'success')
            return redirect(url_for('main.grade_list'))
        except IntegrityError:
            db.session.rollback()
            flash('添加成绩时出错，请检查', 'danger')
    return render_template('grade_form.html', form=form, title='添加成绩')

@bp.route('/grades/edit/<int:id>', methods=['GET', 'POST'])
def grade_edit(id):
    grade = Grade.query.get_or_404(id)
    form = GradeForm(obj=grade)
    form.student.choices = [(s.id, f'{s.student_id} - {s.name}') for s in Student.query.order_by(Student.student_id).all()]
    form.course.choices = [(c.id, f'{c.course_code} - {c.name}') for c in Course.query.order_by(Course.course_code).all()]
    form.student.data = grade.student_id
    form.course.data = grade.course_id
    if form.validate_on_submit():
        if (grade.student_id != form.student.data or grade.course_id != form.course.data):
            exists = Grade.query.filter_by(student_id=form.student.data, course_id=form.course.data).first()
            if exists:
                flash('该学生该课程已有成绩记录，请选择其他或编辑已有记录', 'warning')
                return redirect(url_for('main.grade_edit', id=exists.id))
        grade.student_id = form.student.data
        grade.course_id = form.course.data
        grade.score = form.score.data
        grade.grade_status = form.grade_status.data.strip() or None
        try:
            db.session.commit()
            flash('成绩已更新', 'success')
            return redirect(url_for('main.grade_list'))
        except IntegrityError:
            db.session.rollback()
            flash('更新成绩时出错', 'danger')
    return render_template('grade_form.html', form=form, title='编辑成绩')

@bp.route('/grades/delete/<int:id>', methods=['POST'])
def grade_delete(id):
    grade = Grade.query.get_or_404(id)
    db.session.delete(grade)
    db.session.commit()
    flash('成绩已删除', 'info')
    return redirect(url_for('main.grade_list'))
